﻿using System;

namespace Sunny.FrameDecoder
{
    /// <summary>
    /// CanOpen包模式 - 数据帧解码器
    /// AA 00 00 08 00 00 06 01 2F 00 1A 00 00 00 00 00 
    /// </summary>
    public class CanOpenPackageFrameDecoder : BaseByteFrameDecoder
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="headers">数据头</param>
        /// <param name="length">长度</param>
        public CanOpenPackageFrameDecoder(byte[] headers, int length = 16)
        {
            Headers = headers;
            FixedLength = length;
        }

        ///<inheritdoc/>
        public override BaseByteFrameDecoder Clone()
        {
            return new CanOpenPackageFrameDecoder(Headers, FixedLength);
        }

        /// <summary>
        /// 解码函数
        /// </summary>
        /// <exception cref="System.NotImplementedException"></exception>
        protected override void Decoding()
        {
            while (Cache.WrittenCount >= FixedLength)
            {
                int idx = Cache.WrittenSpan.IndexOf(Headers.AsSpan());
                if (idx > 0) Cache.Remove(idx);

                if (Cache.WrittenCount >= FixedLength)
                {
                    LastDecodedTime = DateTime.Now;
                    ByteFrameEventArgs e = new ByteFrameEventArgs(this, ByteFrameParams.Empty, GetResult(8, FixedLength - 8), GetResult(0, FixedLength));
                    InvokeOnDecoder(e);
                }
            }
        }

        /// <summary>
        /// 数据头部
        /// </summary>
        public byte[] Headers = [0xAA, 0x00, 0x00, 0x08, 0x00, 0x00];

        /// <summary>
        /// 固定长度
        /// </summary>
        public int FixedLength = 16;

        /// <summary>
        /// 准备数据解码
        /// </summary>
        /// <param name="data">输入数据</param>
        /// <returns>判断此数据是否可以解码</returns>
        protected override bool PrepareDecode(ReadOnlySpan<byte> data)
        {
            if (data == null || data.Length == 0)
            {
                DecoderError("The data to be decoded is null.", data);
                return false;
            }

            if (Cache.WrittenCount > 0)
            {
                return true;
            }

            if (data.IndexOf(Headers.AsSpan()) < 0)
            {
                DecoderError("Data header verification failed.", data);
                return false;
            }

            return true;
        }
    }
}
